

import ac = module("utils/commons/array-collection");

/**
	* The list of valid SDMX data types. Most of them are compatible with those
	* found in XML Schema and have equivalents in most current implementation
	* platforms.
	* 
	* @author Xavier Sosnovsky, Anthony Morel
	*/
export class DataType {
		
	/*==============================Fields================================*/
		
	private static _instance:DataType;
		
	private static _dataTypes: ac.ArrayCollection<string>;
		
	/*============================Constants===============================*/
		
	/**
	    * Represents character strings.
	    */
	public static STRING:string = "string";
	    
	/**
	    * Immutable arbitrary-precision integers.
	    */
	public static BIG_INTEGER:string = "bigInteger";
	    
	/**
	    * 32-bit two's complement.
	    */
	public static INTEGER:string = "integer";
	    
	/**
	    * 64-bit two's complement.
	    */
	public static LONG:string = "long";
	    
	/**
	    * 16-bit two's complement.
	    */
	public static SHORT:string = "short";
	    
	/**
	    * Immutable, arbitrary-precision signed decimal numbers.
	    */
	public static DECIMAL:string = "decimal";
	    
	/**
	    * 32-bit IEEE 754.
	    */
	public static FLOAT:string = "float";
	    
	/**
	    * 64-bit IEEE 754.
	    */
	public static DOUBLE:string = "double";
	    
	/**
	    * true or false.
	    */
	public static BOOLEAN:string = "boolean";
	    
	/**
	    * Objects with integer-valued year, month, day, hour and minute 
	    * properties, a decimal-valued second property, and a boolean timezoned 
	    * property.
	    */
	public static DATE_TIME:string = "dateTime";
	    
	/**
	    * An instant of time that recurs every day.
	    */
	public static TIME:string = "time";
	    
	/**
	    * Top-open intervals of exactly one day in length on the timelines of
	    * dateTime, beginning on the beginning moment of each day (in each
	    * timezone), i.e. '00:00:00', up to but not including '24:00:00' (which 
	    * is identical with '00:00:00' of the next day). For nontimezoned 
	    * values, the top-open intervals disjointly cover the nontimezoned 
	    * timeline, one per day. For timezoned values, the intervals begin at 
	    * every minute and therefore overlap.
	    */
	public static DATE:string = "date";
	    
	/**
	    * A gregorian calendar year.
	    */
	public static YEAR:string = "year";
	    
	/**
	    * Gregorian month that recurs every year.
	    */
	public static MONTH:string = "month";
	    
	/**
	    * Gregorian day that recurs, specifically a day of the month such as 
	    * the 5th of the month.
	    */
	public static DAY:string = "day";
	    
	/**
	    * Gregorian date that recurs, specifically a day of the year such as 
	    * the third of May.
	    */
	public static MONTH_DAY:string = "monthDay";
	    
	/**
	    * A specific gregorian month in a specific gregorian year.
	    */
	public static YEAR_MONTH:string = "yearMonth";
	    
	/**
	    * Immutable representation of a time span as defined in the W3C XML 
	    * Schema 1.0 specification. A Duration object represents a period of 
	    * Gregorian time, which consists of six fields (years, months, days, 
	    * hours, minutes, and seconds) plus a sign (+/-) field.
	    */
	public static DURATION:string = "duration";
	    
	/**
	    * Start DataType.Date_Time + DataType.Duration.
	    */
	public static TIME_SPAN:string = "timeSpan";
	    
	/**
	    * Represents a Uniform Resource Identifier (this.URI) reference. Aside from 
	    * some minor deviations noted below, an instance of this class 
	    * represents a .URI reference as defined by RFC 2396: Uniform Resource 
	    * Identifiers (this.URI): Generic Syntax, amended by RFC 2732: Format for 
	    * Literal IPv6 Addresses in URLs.
	    */
	public static URI:string = "uri";
	    
	/**
	    * Value taken from a known system of counts.
	    */
	public static COUNT:string = "count";
	    
	/**
	    * Inclusive range of values.
	    */
	public static INCLUSIVE_VALUE_RANGE:string = 
	    "inclusiveValueRange";
	    
	/**
	    * Exclusive range of values.
	    */
	public static EXCLUSIVE_VALUE_RANGE:string = 
	    "exclusiveValueRange";
	    
	/**
	    * Value taken from an incremental sequence of integer values.
	    */
	public static INCREMENT:string = "increment";
	    
	/**
	    * A union type of DataType.Date, DataType.Time, DataType.Date_Time, and 
	    * a set of codes for common periods.
	    */
	public static OBSERVATIONAL_TIME_PERIOD:string = 
	    "observationalTimePeriod";
	    
	/**
	    * 1 signed byte (two's complement). Covers values from -128 to 127.
	    */
	public static BASE64_BINARY:string = "base64Binary";
	    
	/*===========================Constructor==============================*/
		
	constructor(enforcer:SingletonEnforcer) {
	}
	    
	/*==========================Public methods============================*/
	    
	/**
	    * Whether the supplied dataType is in the list of valid SDMX data 
	    * types.
	    * 
	    * @return true if the supplied dataType is in the list of valid SDMX 
	    * data types, false otherwise.
	    */ 
	public static contains(dataType:string):bool {
	    return this.createDataTypesList().contains(dataType);
	}
	    
	/*=========================Private methods============================*/
	    
	private static createDataTypesList():ac.ArrayCollection<string> {
	    if (null == this._instance) {
            this._instance = new DataType(new SingletonEnforcer());
            this._dataTypes = new ac.ArrayCollection<string>();
            this._dataTypes.addItem(this.STRING);
			this._dataTypes.addItem(this.BIG_INTEGER);
			this._dataTypes.addItem(this.INTEGER);
			this._dataTypes.addItem(this.LONG);
			this._dataTypes.addItem(this.SHORT);
			this._dataTypes.addItem(this.DECIMAL);
			this._dataTypes.addItem(this.FLOAT);
			this._dataTypes.addItem(this.DOUBLE);
			this._dataTypes.addItem(this.BOOLEAN);
			this._dataTypes.addItem(this.DATE_TIME);
			this._dataTypes.addItem(this.TIME);
			this._dataTypes.addItem(this.DATE);
			this._dataTypes.addItem(this.YEAR);
			this._dataTypes.addItem(this.MONTH);
			this._dataTypes.addItem(this.DAY);
			this._dataTypes.addItem(this.MONTH_DAY);
			this._dataTypes.addItem(this.YEAR_.MONTH);
			this._dataTypes.addItem(this.DURATION);
			this._dataTypes.addItem(this.TIME_SPAN);
			this._dataTypes.addItem(this.URI);
			this._dataTypes.addItem(this.COUNT);
			this._dataTypes.addItem(this.INCLUSIVE_VALUE_RANGE);
			this._dataTypes.addItem(this.EXCLUSIVE_VALUE_RANGE);
			this._dataTypes.addItem(this.INCREMENT);
			this._dataTypes.addItem(this.OBSERVATIONAL_TIME_PERIOD);
		   	this._dataTypes.addItem(this.BASE64_BINARY);
		}
        return this._dataTypes;
	}
}
export class SingletonEnforcer {
}